home *** CD-ROM | disk | FTP | other *** search
- // Copyright (C) 1997-2002 Alias|Wavefront,
- // a division of Silicon Graphics Limited.
- //
- // The information in this file is provided for the exclusive use of the
- // licensees of Alias|Wavefront. Such users have the right to use, modify,
- // and incorporate this code into other products for purposes authorized
- // by the Alias|Wavefront license agreement, without fee.
- //
- // ALIAS|WAVEFRONT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
- // INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
- // EVENT SHALL ALIAS|WAVEFRONT BE LIABLE FOR ANY SPECIAL, INDIRECT OR
- // CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
- // DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
- // TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- // PERFORMANCE OF THIS SOFTWARE.
- //
-
- //
- // Description :
- // A script to reparameterize the knot sequence along U of a NURBS Surface to
- // the specified range [a,b].
- // LIMITATIONS :
- // 1. The NURBS surface should have NO history.
- // 2. The "reparametrize" keeps no history.
- // 3. a < b.
- // How to use: select a nurbs Surface (eg. surface1) and enter these commands to
- // reparameterize the surface from 0 to 10:
- //
- // reparameterizeNurbsSurfaceAlongU -10 10; // performs the reparameterization
- // getAttr surface1.minValueU; // will return -10
- // getAttr surface1.maxValueU; // will return 10
- // nurbsSurfaceKnotsAlongU; // will print knot vector of selected surface along U
- //
- //
-
-
- proc float[] rescale(
- float $knots[],
- float $startParm,
- float $endParm )
- //
- // Description :
- // To rescale the knots to lie inbetween [0,1]
- //
- {
- float $scaledKnots[] ;
-
- int $n = size($knots) ;
- if( $n == 0 ) return $scaledKnots ;
-
- float $minKnot = $knots[0] ;
- float $maxKnot = $knots[0] ;
- int $i ;
-
- // get min, max knot.
- //
- for( $i = 1 ; $i < $n ; $i++ ) {
- $minKnot = `min $minKnot $knots[$i]` ;
- $maxKnot = `max $minKnot $knots[$i]` ;
- }
- float $newMin = $startParm ;
- float $newMax = $endParm ;
- float $diff = $maxKnot - $minKnot ;
- float $scaleFactor = $endParm - $startParm ;
- float $scale = $scaleFactor / $diff ;
- for( $i = 0 ; $i < $n ; $i++ ) {
- float $v = ( $knots[$i] - $minKnot ) ;
- $scaledKnots[$i] = $newMin + ($v * $scale) ;
- }
- return $scaledKnots ;
- }
-
- proc string buildTemporarySurface(
- float $knotsU[],
- int $degu,
- int $nsu,
- int $fu,
- float $knotsV[],
- int $degv,
- int $nsv,
- int $fv)
- //
- // Description :
- // To build a temporary surface
- //
- {
-
- int $nu = size($knotsU) ;
- if( $nu == 0 || $nsu == 0 ) return " " ;
- int $nv = size($knotsV) ;
- if( $nv == 0 || $nsv == 0 ) return " " ;
-
- int $i, $j ;
-
- // append degree.
- //
- string $args ;
- $args = "surface " ;
- $args = $args + " -du " + $degu ;
- $args = $args + " -dv " + $degv ;
-
- // knot sequence along U.
- //
- for( $i = 0 ; $i < $nu ; $i++ ) {
- $args = $args + " -ku " + $knotsU[$i] ;
- }
-
- // knot sequence along V.
- //
- for( $i = 0 ; $i < $nv ; $i++ ) {
- $args = $args + " -kv " + $knotsV[$i] ;
- }
-
- // form u.
- //
- string $formU ;
- if( $fu == 0 ) $formU = " open " ;
- else if( $fu == 1 ) $formU = " closed " ;
- else $formU = " periodic " ;
- $args = $args + " -fu " + $formU ;
-
- // form v.
- //
- string $formV ;
- if( $fv == 0 ) $formV = " open " ;
- else if( $fv == 1 ) $formV = " closed " ;
- else $formV = " periodic " ;
- $args = $args + " -fv " + $formV ;
-
- // control points
- //
- int $ncvu = $degu + $nsu ;
- int $ncvv = $degv + $nsv ;
-
- for( $i = 0 ; $i < $ncvu ; $i++ ) {
- for( $j = 0 ; $j < $ncvv ; $j++ ) {
- float $v = 0.0 ;
- $args = $args + " -p " + $v ;
- $args = $args + " " + $v ;
- $args = $args + " " + $v ;
- } // for $j
- } // for $i.
-
- string $srfName = eval($args) ;
- return $srfName ;
- }
-
- proc int rebuildSurfaceToMatchKnots( string $srf, string $matchSrf, int $dir )
- //
- // Description :
- //
- {
- int $ok = 1 ;
- string $nodes[] ;
- if( catch( $nodes = `rebuildSurface -ch false -rpo true -fr false -dir $dir -rt 2 $srf $matchSrf` ) ) {
- string $dirStr = " U and V " ;
- if ($dir == 0 ) $dirStr = " U " ;
- if( $dir == 1 ) $dirStr = " V " ;
- string $wstr = "rebuild to match knots in " ;
- $wstr = $wstr + $dirStr ;
- $wstr = $wstr + " failed. " ;
- warning $wstr ;
- $ok = 0 ;
- }
- return $ok ;
- }
-
- global proc int reparameterizeNurbsSurfaceAlongU(
- float $startParm,
- float $endParm )
- //
- // Description :
- // To reparametrize the knot sequence of the nurbs surface
- // along U to be in the range [$startParm, $endParam].
- // NOTE : works on a NURBS surface of the selection list.
- //
- {
-
- // valid parameters ?
- //
- if( $startParm >= $endParm ) {
- error "start Parameter should be less than end Parameter" ;
- return 0 ;
- }
-
-
- // 0. Grab the select list.
- //
- string $selList[] ;
- $selList = `ls -sl` ;
-
- // 1. Run filter to select only the NURBS curves.
- //
- global int $gSelectNurbsSurfacesBit ;
- string $srfList[] ;
- $srfList = `filterExpand -ex true -sm $gSelectNurbsSurfacesBit $selList` ;
- if( size($srfList) == 0 ) {
- warning "No NURBS surface selected" ;
- return 1;
- }
-
- // 2. Work on the last item if more than one NURBS surface in list.
- //
- int $len = size($srfList) ;
- string $lastSrf = $srfList[$len-1] ;
- if( $len != 1 ) {
- string $w = " reparameterizing Knots along U for the last NURBS surface: " + $lastSrf ;
- warning $w ;
- }
-
- // 2.0 Check if surface has history.
- //
- string $hist[] = `listHistory -gl true -pdo true -lf true -f false $lastSrf` ;
- if( size($hist) > 0 ) {
- error "surface has history, reparameterize is pointless" ;
- return 1 ;
- }
-
- // 2.1 Get the degree.
- //
- int $degu ;
- string $inAttr = $lastSrf + ".degreeU" ;
- $degu = `getAttr $inAttr` ;
-
- int $degv ;
- $inAttr = $lastSrf + ".degreeV" ;
- $degv = `getAttr $inAttr` ;
-
- int $nsu ;
- $inAttr = $lastSrf + ".su" ;
- $nsu = `getAttr $inAttr` ;
-
- int $nsv ;
- $inAttr = $lastSrf + ".sv" ;
- $nsv = `getAttr $inAttr` ;
-
- int $fu ;
- $inAttr = $lastSrf + ".fu" ;
- $fu = `getAttr $inAttr` ;
-
- int $fv ;
- $inAttr = $lastSrf + ".fv" ;
- $fv = `getAttr $inAttr` ;
-
- // 3. Extract the Knots.
- //
- float $knotsU[] ;
- float $knotsV[] ;
- select -r $lastSrf ;
- $knotsU = nurbsSurfaceKnotsAlongU() ;
- $knotsV = nurbsSurfaceKnotsAlongV() ;
- // 4. Scale the Knot Sequence to lie in between [$startParm, $endParm].
- //
- float $sKnotsU[] ;
- $sKnotsU = rescale( $knotsU, $startParm, $endParm ) ;
-
- // 5. Build a temporary surface with the scaled Knots
- //
- int $okay = 1 ;
- string $tmpSurface ;
- $tmpSurface = buildTemporarySurface( $sKnotsU, $degu, $nsu, $fu, $knotsV, $degv, $nsv, $fv ) ;
- if( $tmpSurface == " " ) {
- $okay = 0 ;
- }
-
- // 6. Rebuild surface inplace to match knots in the U direction.
- //
- if( $okay == 1 ) {
- int $dir = 0 ;
- $okay = rebuildSurfaceToMatchKnots( $lastSrf, $tmpSurface, $dir ) ;
- delete $tmpSurface ;
- }
-
- // 7. select surface for which knots are reparameterized.
- //
- select -r $lastSrf ;
-
- return $okay ;
- }
-
-